package com.libui.navigatonbar.menuview

import android.content.Context
import android.graphics.Color
import android.graphics.Typeface
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.AbsoluteSizeSpan
import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.core.text.toSpannable
import com.libui.IconFonts
import com.libui.R
import com.libui.TextViewEx
import com.libui.navigatonbar.MenuData
import com.libui.navigatonbar.OnMenuTap
import razerdp.basepopup.BasePopupWindow

class TitleMenuView @JvmOverloads constructor(
    mContext: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    private var menuData: MenuData? = null,
    private var onMenuTap: OnMenuTap? = null,
) : LinearLayout(
    mContext, attrs, defStyleAttr
) {
    companion object {
        const val ICON_FONT_PREFIX = "icon,"
    }

    private var iconView: ImageView
    private var titleView: TextViewEx

    init {
        LayoutInflater.from(context).inflate(R.layout.title_menu_view, this, true)

        iconView = findViewById(R.id.icon)

        titleView = findViewById(R.id.title)
        titleView.setTextColor(Color.WHITE)
        titleView.textSize = 16F

        setOnClickListener {
            menuData?.children?.let { children ->
                PopMenuView(context, children).also {
                    it.onMenuTap = { menuData ->
                        it.dismiss(true)

                        onMenuTap?.let { it(menuData) }
                    }
                }
                    .setPopupGravityMode(
                        BasePopupWindow.GravityMode.ALIGN_TO_ANCHOR_SIDE,
                        BasePopupWindow.GravityMode.RELATIVE_TO_ANCHOR
                    )
                    .setPopupGravity(Gravity.END or Gravity.BOTTOM)
                    .setOffsetX(context.resources.getDimensionPixelSize(R.dimen.navigation_bar_margin))
                    .setOffsetY(context.resources.getDimensionPixelSize(R.dimen.navigation_bar_margin))
                    .showPopupWindow(it)
            }

            onMenuTap?.let { it(menuData) }
        }
    }

    private fun appendIconFont(
        builder: SpannableStringBuilder,
        iconWithTag: String,
        menuData: MenuData
    ) {
        val iconFontStr = iconWithTag.substring(ICON_FONT_PREFIX.length)
        val text = IconFonts.instance.dataSource?.iconFonts?.get(iconFontStr) ?: return

        appendSpannableString(builder, text, menuData)
    }

    private fun appendSpannableString(
        builder: SpannableStringBuilder,
        text: String,
        menuData: MenuData
    ) {
        builder.append(
            text,
            AbsoluteSizeSpan(menuData.style?.fontData?.fontSize?.toInt() ?: 16, true),
            Spanned.SPAN_INCLUSIVE_EXCLUSIVE
        )
    }

    fun setMenuData(menuData: MenuData, onMenuTap: OnMenuTap? = null) {
        this.menuData = menuData
        this.onMenuTap = onMenuTap

        val spannableStringBuilder = SpannableStringBuilder()

        if (menuData.icon != null) {
            if (menuData.icon.startsWith(ICON_FONT_PREFIX)) {
                iconView.visibility = View.GONE
                appendIconFont(spannableStringBuilder, menuData.icon, menuData)
            } else {
                iconView.visibility = View.VISIBLE
            }
        } else {
            iconView.visibility = View.GONE
        }

        if (menuData.title != null) {
            if (spannableStringBuilder.isNotEmpty()) {
                spannableStringBuilder.append(" ")
            }

            if (menuData.title.startsWith(ICON_FONT_PREFIX)) {
                appendIconFont(spannableStringBuilder, menuData.title, menuData)
            } else {
                appendSpannableString(spannableStringBuilder, menuData.title, menuData)
            }
        }

        if (spannableStringBuilder.isNotEmpty()) {
            titleView.visibility = View.VISIBLE

            titleView.text = spannableStringBuilder.toSpannable()
        } else {
            titleView.visibility = View.GONE
        }

        isEnabled = menuData.enabled
    }

    fun setTextColor(color: Int) {
        titleView.setTextColor(color)
    }
}